package com.atguigu.netty.simple;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

/*
说明
1.我们自定义一个Handler 需要继承netty 规定好的某个HandlerAdapter
2.这时我们自定义一个Handler ，才能称为一个handler
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    //读取数据事件（这里我们可以读取客户端发送的消息）
    /*
    1.ChannelHandlerContext ctx:上下文对象，含有 管道pipeline ,通道channel，地址
    2.Object msg：就是客户端发送的数据 默认Object
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //比如这里我们有一个非常耗时长的业务 -> 异步执行 -> 提交该channel对应的
        //NIOEventLoop到taskQueue中

        //解决方案1：用户程序自定义普通任务
        ctx.channel().eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端2",CharsetUtil.UTF_8));
            }
        });

        ctx.channel().eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(20 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端3",CharsetUtil.UTF_8));
            }
        });

        //用户自定义定时任务 -> 该任务是提交到scheduleTaskQueue中
        ctx.channel().eventLoop().schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(20 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端4",CharsetUtil.UTF_8));
            }
        },5, TimeUnit.SECONDS);

        System.out.println("go on...");

//        System.out.println("server thread :" + Thread.currentThread().getName());
//        System.out.println("server ctx=" + ctx);
//        System.out.println("看看channel 和 pipeline");
//        Channel channel = ctx.channel();
//        ChannelPipeline pipeline = ctx.pipeline();
//        //将msg 转成一个ByteBuf
//        //ByteBuf 是netty 提供的，不是NIO 的ByteBuffer
//        ByteBuf buf = (ByteBuf) msg;
//        System.out.println("客户端发送的消息是：" + buf.toString(CharsetUtil.UTF_8));
//        System.out.println("客户端地址：" + channel.remoteAddress());
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //writeAndFlush 是write + flush
        //将数据写入到缓存，并刷新
        //一般讲，我们对这个发送的数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端1",CharsetUtil.UTF_8));
    }

    //处理异常，一般是需要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
